package com.slimbloody;

import com.google.protobuf.ByteString;
import com.google.protobuf.Int64Value;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat;
import io.grpc.StatusRuntimeException;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;
import org.tensorflow.framework.DataType;
import org.tensorflow.framework.TensorProto;
import org.tensorflow.framework.TensorShapeProto;
import tensorflow.serving.Model;
import tensorflow.serving.Predict;
import tensorflow.serving.PredictionServiceGrpc;

import java.util.*;


@Service
@Slf4j
public class CallService {
  @GrpcClient(
    value="tf-serving-agent",
    interceptors={GzipGrpcInterceptor.class}
  )
  private PredictionServiceGrpc.PredictionServiceBlockingStub predictionServiceStub;

  @Autowired
  private ModelConfig modelConfig;

  public String callHalf() {
    Predict.PredictRequest.Builder reqBuilder = Predict.PredictRequest.newBuilder();

    Model.ModelSpec modelSpec = getModelSpec();
    reqBuilder.setModelSpec(modelSpec);

    TensorProto tensor = TensorProto.newBuilder()
      .addAllFloatVal(Arrays.asList(1.0f, 2.0f, 5.0f))
      // .addFloatVal(1.0f)
      // .addFloatVal(2.0f)
      // .addFloatVal(5.0f)
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(3))  // batch
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))  // feature dim
      )
      .build();

    reqBuilder.putInputs("x", tensor);

    Predict.PredictRequest predictRequest = reqBuilder.build();

    return invoke(predictRequest);
  }

  private static final ByteString defaultStrVal = ByteString.copyFromUtf8("[UNK]");

  private static final String defaultSignatureName = "serving_default";

  public String callzh(Integer size) {
    Predict.PredictRequest.Builder reqBuilder = Predict.PredictRequest.newBuilder();

    Model.ModelSpec modelSpec = getModelSpec();
    reqBuilder.setModelSpec(modelSpec);

    Map<String, TensorProto> inputs = getTensorProtoMap(size);

    reqBuilder.putAllInputs(inputs);
    Predict.PredictRequest predictRequest = reqBuilder.build();

    return invoke(predictRequest);
  }

  private Model.ModelSpec getModelSpec() {
    Model.ModelSpec.Builder modelSpecBuilder = Model.ModelSpec.newBuilder();
    modelSpecBuilder.setName(modelConfig.getModelSpec().getName());

    Long version = Optional.ofNullable(modelConfig)
      .map(ModelConfig::getModelSpec)
      .map(ModelConfig.ModelSpec::getVersion)
      .orElse(null);
    if (Objects.nonNull(version)) {
      modelSpecBuilder.setVersion(Int64Value.of(version));
    }

    String label = Optional.ofNullable(modelConfig)
      .map(ModelConfig::getModelSpec)
      .map(ModelConfig.ModelSpec::getLabel)
      .orElse(null);
    if (Strings.isNotBlank(label)) {
      modelSpecBuilder.setVersionLabel(label);
    }

    String signatureName = Optional.ofNullable(modelConfig)
      .map(ModelConfig::getModelSpec)
      .map(ModelConfig.ModelSpec::getSignatureName)
      .orElse(defaultSignatureName);
    if (Strings.isNotBlank(signatureName)) {
      modelSpecBuilder.setSignatureName(signatureName);
    }

    Model.ModelSpec modelSpec = modelSpecBuilder.build();
    return modelSpec;
  }

  private static Map<String, TensorProto> getTensorProtoMap(Integer size) {
    Map<String, TensorProto> inputs = new HashMap<>();
    TensorShapeProto.Dim dim = TensorShapeProto.Dim.newBuilder().setSize(size).build();

    // user_id
    TensorProto userIdTensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("user_id", userIdTensor);

// store_id
    TensorProto storeIdTensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("store_id", storeIdTensor);

// search_key
    TensorProto searchKeyTensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("search_key", searchKeyTensor);

// wholesale_id
    TensorProto wholesaleIdTensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("wholesale_id", wholesaleIdTensor);

// platform
    TensorProto platformTensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("platform", platformTensor);

// max_display_wholesaleid_index
    TensorProto maxDisplayWholesaleIdIndexTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("max_display_wholesaleid_index", maxDisplayWholesaleIdIndexTensor);

// display_wholesaleid_index
    TensorProto displayWholesaleIdIndexTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("display_wholesaleid_index", displayWholesaleIdIndexTensor);

// display_index_rate
    TensorProto displayIndexRateTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("display_index_rate", displayIndexRateTensor);

// drug_id_top1
    TensorProto drugIdTop1Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("drug_id_top1", drugIdTop1Tensor);

// drug_id_top2
    TensorProto drugIdTop2Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("drug_id_top2", drugIdTop2Tensor);

// drug_id_top3
    TensorProto drugIdTop3Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("drug_id_top3", drugIdTop3Tensor);

// drug_provider_id_top1
    TensorProto drugProviderIdTop1Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("drug_provider_id_top1", drugProviderIdTop1Tensor);

// drug_provider_id_top2
    TensorProto drugProviderIdTop2Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("drug_provider_id_top2", drugProviderIdTop2Tensor);

// drug_provider_id_top3
    TensorProto drugProviderIdTop3Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("drug_provider_id_top3", drugProviderIdTop3Tensor);

// wholesale_type_top1
    TensorProto wholesaleTypeTop1Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("wholesale_type_top1", wholesaleTypeTop1Tensor);

// wholesale_type_top2
    TensorProto wholesaleTypeTop2Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("wholesale_type_top2", wholesaleTypeTop2Tensor);

// wholesale_type_top3
    TensorProto wholesaleTypeTop3Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("wholesale_type_top3", wholesaleTypeTop3Tensor);

// province_area_name_top1
    TensorProto provinceAreaNameTop1Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("province_area_name_top1", provinceAreaNameTop1Tensor);

// province_area_name_top2
    TensorProto provinceAreaNameTop2Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("province_area_name_top2", provinceAreaNameTop2Tensor);


// category3_id_top1
    TensorProto category3IdTop1Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("category3_id_top1", category3IdTop1Tensor);

// category3_id_top2
    TensorProto category3IdTop2Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("category3_id_top2", category3IdTop2Tensor);

// category3_id_top3
    TensorProto category3IdTop3Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("category3_id_top3", category3IdTop3Tensor);

// category2_id_top1
    TensorProto category2IdTop1Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("category2_id_top1", category2IdTop1Tensor);

// category2_id_top2
    TensorProto category2IdTop2Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("category2_id_top2", category2IdTop2Tensor);

// category2_id_top3
    TensorProto category2IdTop3Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("category2_id_top3", category2IdTop3Tensor);

// category1_id_top1
    TensorProto category1IdTop1Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("category1_id_top1", category1IdTop1Tensor);

// category1_id_top2
    TensorProto category1IdTop2Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("category1_id_top2", category1IdTop2Tensor);

// category1_id_top3
    TensorProto category1IdTop3Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("category1_id_top3", category1IdTop3Tensor);

// brand_top1
    TensorProto brandTop1Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("brand_top1", brandTop1Tensor);

// brand_top2
    TensorProto brandTop2Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("brand_top2", brandTop2Tensor);

// brand_top3
    TensorProto brandTop3Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("brand_top3", brandTop3Tensor);

// factory_name_top1
    TensorProto factoryNameTop1Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("factory_name_top1", factoryNameTop1Tensor);

// factory_name_top2
    TensorProto factoryNameTop2Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("factory_name_top2", factoryNameTop2Tensor);

// factory_name_top3
    TensorProto factoryNameTop3Tensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("factory_name_top3", factoryNameTop3Tensor);

    // last_activate_dt
    TensorProto lastActivateDtTensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("last_activate_dt", lastActivateDtTensor);

    // province_area_code
    TensorProto provinceAreaCodeTensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("province_area_code", provinceAreaCodeTensor);

    // corp_property
    TensorProto corpPropertyTensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("corp_property", corpPropertyTensor);

    // sub_type
    TensorProto subTypeTensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("sub_type", subTypeTensor);


    // real_sub_type
    TensorProto realSubTypeTensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("real_sub_type", realSubTypeTensor);

// is_medinsurance
    TensorProto isMedinsuranceTensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("is_medinsurance", isMedinsuranceTensor);

// amount_1d
    TensorProto amount1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("amount_1d", amount1dTensor);

// total_price_1d
    TensorProto totalPrice1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("total_price_1d", totalPrice1dTensor);

// avg_price_1d
    TensorProto avgPrice1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("avg_price_1d", avgPrice1dTensor);

// order_cnt_1d
    TensorProto orderCnt1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("order_cnt_1d", orderCnt1dTensor);

// user_cnt_1d
    TensorProto userCnt1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("user_cnt_1d", userCnt1dTensor);

// drugstore_branch_cnt_1d
    TensorProto drugstoreBranchCnt1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("drugstore_branch_cnt_1d", drugstoreBranchCnt1dTensor);

// sale_rank_1d
    TensorProto saleRank1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("sale_rank_1d", saleRank1dTensor);

// sale_percent_rank_1d
    TensorProto salePercentRank1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("sale_percent_rank_1d", salePercentRank1dTensor);

// sale_percent_1d
    TensorProto salePercent1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("sale_percent_1d", salePercent1dTensor);

// amount_3d
    TensorProto amount3dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("amount_3d", amount3dTensor);

// total_price_3d
    TensorProto totalPrice3dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("total_price_3d", totalPrice3dTensor);

// avg_price_3d
    TensorProto avgPrice3dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("avg_price_3d", avgPrice3dTensor);

// order_cnt_3d
    TensorProto orderCnt3dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("order_cnt_3d", orderCnt3dTensor);

// user_cnt_3d
    TensorProto userCnt3dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("user_cnt_3d", userCnt3dTensor);

// drugstore_branch_cnt_3d
    TensorProto drugstoreBranchCnt3dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("drugstore_branch_cnt_3d", drugstoreBranchCnt3dTensor);

// sale_rank_3d
    TensorProto saleRank3dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("sale_rank_3d", saleRank3dTensor);

// sale_percent_rank_3d
    TensorProto salePercentRank3dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("sale_percent_rank_3d", salePercentRank3dTensor);

// sale_percent_3d
    TensorProto salePercent3dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("sale_percent_3d", salePercent3dTensor);

// amount_7d
    TensorProto amount7dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("amount_7d", amount7dTensor);

// total_price_7d
    TensorProto totalPrice7dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("total_price_7d", totalPrice7dTensor);

// avg_price_7d
    TensorProto avgPrice7dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("avg_price_7d", avgPrice7dTensor);

// order_cnt_7d
    TensorProto orderCnt7dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("order_cnt_7d", orderCnt7dTensor);

// user_cnt_7d
    TensorProto userCnt7dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("user_cnt_7d", userCnt7dTensor);

// drugstore_branch_cnt_7d
    TensorProto drugstoreBranchCnt7dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("drugstore_branch_cnt_7d", drugstoreBranchCnt7dTensor);

// sale_rank_7d
    TensorProto saleRank7dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("sale_rank_7d", saleRank7dTensor);

// sale_percent_rank_7d
    TensorProto salePercentRank7dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("sale_percent_rank_7d", salePercentRank7dTensor);

// sale_percent_7d
    TensorProto salePercent7dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("sale_percent_7d", salePercent7dTensor);

// amount_31d
    TensorProto amount31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("amount_31d", amount31dTensor);

// total_price_31d
    TensorProto totalPrice31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("total_price_31d", totalPrice31dTensor);

// avg_price_31d
    TensorProto avgPrice31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("avg_price_31d", avgPrice31dTensor);

// order_cnt_31d
    TensorProto orderCnt31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("order_cnt_31d", orderCnt31dTensor);

// user_cnt_31d
    TensorProto userCnt31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("user_cnt_31d", userCnt31dTensor);

// drugstore_branch_cnt_31d
    TensorProto drugstoreBranchCnt31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("drugstore_branch_cnt_31d", drugstoreBranchCnt31dTensor);

// sale_rank_31d
    TensorProto saleRank31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("sale_rank_31d", saleRank31dTensor);

// sale_percent_rank_31d
    TensorProto salePercentRank31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("sale_percent_rank_31d", salePercentRank31dTensor);

// sale_percent_31d
    TensorProto salePercent31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("sale_percent_31d", salePercent31dTensor);

// display_cnt_1d
    TensorProto displayCnt1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("display_cnt_1d", displayCnt1dTensor);

// click_cnt_1d
    TensorProto clickCnt1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("click_cnt_1d", clickCnt1dTensor);

// add_cart_cnt_1d
    TensorProto addCartCnt1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("add_cart_cnt_1d", addCartCnt1dTensor);

// click_rate_1d
    TensorProto clickRate1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("click_rate_1d", clickRate1dTensor);

// add_cart_rate_1d
    TensorProto addCartRate1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("add_cart_rate_1d", addCartRate1dTensor);

// click_or_add_cart_cnt_1d
    TensorProto clickOrAddCartCnt1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("click_or_add_cart_cnt_1d", clickOrAddCartCnt1dTensor);

// click_or_add_cart_rate_1d
    TensorProto clickOrAddCartRate1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("click_or_add_cart_rate_1d", clickOrAddCartRate1dTensor);

// search_rank_1d
    TensorProto searchRank1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("search_rank_1d", searchRank1dTensor);

// search_percent_rank_1d
    TensorProto searchPercentRank1dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("search_percent_rank_1d", searchPercentRank1dTensor);

// display_cnt_3d
    TensorProto displayCnt3dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("display_cnt_3d", displayCnt3dTensor);

// click_cnt_3d
    TensorProto clickCnt3dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("click_cnt_3d", clickCnt3dTensor);

// add_cart_cnt_3d
    TensorProto addCartCnt3dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("add_cart_cnt_3d", addCartCnt3dTensor);

// click_rate_3d
    TensorProto clickRate3dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("click_rate_3d", clickRate3dTensor);

// add_cart_rate_3d
    TensorProto addCartRate3dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("add_cart_rate_3d", addCartRate3dTensor);

// add_cart_rate_7d
    TensorProto addCartRate7dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("add_cart_rate_7d", addCartRate7dTensor);

// click_or_add_cart_cnt_7d
    TensorProto clickOrAddCartCnt7dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("click_or_add_cart_cnt_7d", clickOrAddCartCnt7dTensor);

// click_or_add_cart_rate_7d
    TensorProto clickOrAddCartRate7dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("click_or_add_cart_rate_7d", clickOrAddCartRate7dTensor);

// search_rank_7d
    TensorProto searchRank7dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("search_rank_7d", searchRank7dTensor);

    // search_percent_rank_7d
    TensorProto searchPercentRank7dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("search_percent_rank_7d", searchPercentRank7dTensor);

// display_cnt_31d
    TensorProto displayCnt31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("display_cnt_31d", displayCnt31dTensor);

// click_cnt_31d
    TensorProto clickCnt31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("click_cnt_31d", clickCnt31dTensor);

// add_cart_cnt_31d
    TensorProto addCartCnt31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("add_cart_cnt_31d", addCartCnt31dTensor);

// click_rate_31d
    TensorProto clickRate31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("click_rate_31d", clickRate31dTensor);

// add_cart_rate_31d
    TensorProto addCartRate31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("add_cart_rate_31d", addCartRate31dTensor);

// click_or_add_cart_cnt_31d
    TensorProto clickOrAddCartCnt31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("click_or_add_cart_cnt_31d", clickOrAddCartCnt31dTensor);

// click_or_add_cart_rate_31d
    TensorProto clickOrAddCartRate31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("click_or_add_cart_rate_31d", clickOrAddCartRate31dTensor);

// search_rank_31d
    TensorProto searchRank31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("search_rank_31d", searchRank31dTensor);

// search_percent_rank_31d
    TensorProto searchPercentRank31dTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("search_percent_rank_31d", searchPercentRank31dTensor);

// drug_id
    TensorProto drugIdTensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("drug_id", drugIdTensor);

// provider_id
    TensorProto providerIdTensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("provider_id", providerIdTensor);

// delivery_provider_id
    TensorProto deliveryProviderIdTensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("delivery_provider_id", deliveryProviderIdTensor);

// begin_ts
    TensorProto beginTsTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, 0f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("begin_ts", beginTsTensor);

// end_ts
    TensorProto endTsTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, 0f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("end_ts", endTsTensor);

// wholesale_type
    TensorProto wholesaleTypeTensor = TensorProto.newBuilder()
      .addAllStringVal(Collections.nCopies(size, defaultStrVal))
      .setDtype(DataType.DT_STRING)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
      )
      .build();
    inputs.put("wholesale_type", wholesaleTypeTensor);

// min_amount
    TensorProto minAmountTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("min_amount", minAmountTensor);

// max_amount
    TensorProto maxAmountTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("max_amount", maxAmountTensor);

// unit_price
    TensorProto unitPriceTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("unit_price", unitPriceTensor);

// stock_balance
    TensorProto stockBalanceTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("stock_balance", stockBalanceTensor);

    // stock_available
    TensorProto stockAvailableTensor = TensorProto.newBuilder()
      .addAllFloatVal(Collections.nCopies(size, -1f))
      .setDtype(DataType.DT_FLOAT)
      .setTensorShape(TensorShapeProto.newBuilder()
        .addDim(dim)
        .addDim(TensorShapeProto.Dim.newBuilder().setSize(1))
      )
      .build();
    inputs.put("stock_available", stockAvailableTensor);
    return inputs;
  }

  private String invoke(Predict.PredictRequest predictRequest) {
    try {
      Predict.PredictResponse predictResponse = predictionServiceStub.predict(predictRequest);
      JsonFormat.Printer printer = JsonFormat.printer();
      String json = printer.print(predictResponse);
      return json;
    } catch (final StatusRuntimeException e) {
      log.error("FAILED with {}", e.getStatus().getCode());
    } catch (InvalidProtocolBufferException e) {
      throw new RuntimeException(e);
    }
    return null;
  }
}








